import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * Other Common Classes Examples
 * This class demonstrates the usage of various common classes in Java
 */
public class OtherCommonClasses {
    
    public static void main(String[] args) {
        OtherCommonClasses example = new OtherCommonClasses();
        
        // Demonstrating Date and Calendar classes
        example.demonstrateDateAndCalendar();
        
        // Demonstrating LocalDate, LocalTime, LocalDateTime (Java 8+ Time API)
        example.demonstrateJavaTimeApi();
        
        // Demonstrating Math class
        example.demonstrateMathClass();
        
        // Demonstrating Random class
        example.demonstrateRandomClass();
        
        // Demonstrating Scanner class
        // Note: Scanner demonstration requires user input, so it's shown in comments
        example.explainScannerClass();
        
        // Demonstrating System class
        example.demonstrateSystemClass();
    }
    
    /**
     * Method to demonstrate Date and Calendar classes
     */
    public void demonstrateDateAndCalendar() {
        System.out.println("=== Date and Calendar Classes ===");
        
        // Date class examples
        Date currentDate = new Date();
        System.out.println("Current date: " + currentDate);
        System.out.println("Time in milliseconds: " + currentDate.getTime());
        
        // Calendar class examples
        Calendar calendar = Calendar.getInstance();
        System.out.println("Current year: " + calendar.get(Calendar.YEAR));
        System.out.println("Current month: " + (calendar.get(Calendar.MONTH) + 1)); // Month is 0-based
        System.out.println("Current day: " + calendar.get(Calendar.DAY_OF_MONTH));
        
        // Setting specific date
        calendar.set(2025, Calendar.JANUARY, 1);
        System.out.println("Set date: " + calendar.getTime());
        
        System.out.println();
    }
    
    /**
     * Method to demonstrate LocalDate, LocalTime, LocalDateTime (Java 8+ Time API)
     */
    public void demonstrateJavaTimeApi() {
        System.out.println("=== Java 8+ Time API ===");
        
        // LocalDate examples
        LocalDate today = LocalDate.now();
        System.out.println("Today's date: " + today);
        
        LocalDate specificDate = LocalDate.of(2025, 1, 1);
        System.out.println("Specific date: " + specificDate);
        
        // LocalTime examples
        LocalTime currentTime = LocalTime.now();
        System.out.println("Current time: " + currentTime);
        
        LocalTime specificTime = LocalTime.of(10, 30, 45);
        System.out.println("Specific time: " + specificTime);
        
        // LocalDateTime examples
        LocalDateTime currentDateTime = LocalDateTime.now();
        System.out.println("Current date and time: " + currentDateTime);
        
        LocalDateTime specificDateTime = LocalDateTime.of(2025, Month.JANUARY, 1, 10, 30);
        System.out.println("Specific date and time: " + specificDateTime);
        
        // Formatting examples
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String formattedDateTime = currentDateTime.format(formatter);
        System.out.println("Formatted date and time: " + formattedDateTime);
        
        // Parsing examples
        LocalDate parsedDate = LocalDate.parse("2025-01-01");
        System.out.println("Parsed date: " + parsedDate);
        
        System.out.println();
    }
    
    /**
     * Method to demonstrate Math class
     */
    public void demonstrateMathClass() {
        System.out.println("=== Math Class ===");
        
        double x = 25.0;
        double y = 4.0;
        
        // Basic math functions
        System.out.println("Square root of " + x + ": " + Math.sqrt(x));
        System.out.println(x + " raised to the power of " + y + ": " + Math.pow(x, y));
        System.out.println("Absolute value of -" + x + ": " + Math.abs(-x));
        
        // Trigonometric functions
        double angle = Math.PI / 4; // 45 degrees
        System.out.println("Sin of 45 degrees: " + Math.sin(angle));
        System.out.println("Cos of 45 degrees: " + Math.cos(angle));
        System.out.println("Tan of 45 degrees: " + Math.tan(angle));
        
        // Rounding functions
        double decimal = 12.75;
        System.out.println("Ceiling of " + decimal + ": " + Math.ceil(decimal));
        System.out.println("Floor of " + decimal + ": " + Math.floor(decimal));
        System.out.println("Round of " + decimal + ": " + Math.round(decimal));
        
        // Maximum and minimum
        System.out.println("Maximum of " + x + " and " + y + ": " + Math.max(x, y));
        System.out.println("Minimum of " + x + " and " + y + ": " + Math.min(x, y));
        
        // Random number (between 0.0 and 1.0)
        System.out.println("Random number: " + Math.random());
        
        System.out.println();
    }
    
    /**
     * Method to demonstrate Random class
     */
    public void demonstrateRandomClass() {
        System.out.println("=== Random Class ===");
        
        Random random = new Random();
        
        // Random integers
        int randomInt = random.nextInt();
        System.out.println("Random integer: " + randomInt);
        
        // Random integer within range (0-99)
        int randomIntRange = random.nextInt(100);
        System.out.println("Random integer (0-99): " + randomIntRange);
        
        // Random doubles
        double randomDouble = random.nextDouble();
        System.out.println("Random double (0.0-1.0): " + randomDouble);
        
        // Random booleans
        boolean randomBoolean = random.nextBoolean();
        System.out.println("Random boolean: " + randomBoolean);
        
        // Random bytes
        byte[] randomBytes = new byte[5];
        random.nextBytes(randomBytes);
        System.out.print("Random bytes: ");
        for (byte b : randomBytes) {
            System.out.print(b + " ");
        }
        System.out.println();
        
        System.out.println();
    }
    
    /**
     * Method to explain Scanner class
     */
    public void explainScannerClass() {
        System.out.println("=== Scanner Class ===");
        System.out.println("Scanner class is used to get user input:");
        System.out.println("// Scanner scanner = new Scanner(System.in);");
        System.out.println("// System.out.print(\"Enter your name: \");");
        System.out.println("// String name = scanner.nextLine();");
        System.out.println("// System.out.print(\"Enter your age: \");");
        System.out.println("// int age = scanner.nextInt();");
        System.out.println("// scanner.close();");
        System.out.println();
    }
    
    /**
     * Method to demonstrate System class
     */
    public void demonstrateSystemClass() {
        System.out.println("=== System Class ===");
        
        // System.out examples
        System.out.println("This is printed using System.out.println()");
        System.err.println("This is printed using System.err.println()");
        
        // Current time in milliseconds
        long currentTimeMillis = System.currentTimeMillis();
        System.out.println("Current time in milliseconds: " + currentTimeMillis);
        
        // Environment properties
        String javaVersion = System.getProperty("java.version");
        System.out.println("Java version: " + javaVersion);
        
        String osName = System.getProperty("os.name");
        System.out.println("Operating system: " + osName);
        
        // Array copying
        int[] sourceArray = {1, 2, 3, 4, 5};
        int[] destArray = new int[5];
        System.arraycopy(sourceArray, 0, destArray, 0, sourceArray.length);
        System.out.print("Copied array: ");
        for (int value : destArray) {
            System.out.print(value + " ");
        }
        System.out.println();
        
        // Exiting the program
        System.out.println("Program would exit with System.exit(0) - commented out for demo purposes");
        // System.exit(0);
        
        System.out.println();
    }
}